
#include "mlVec3.h"

namespace ml
{

	Vec3::Vec3()
	{
		zero();
	}

	Vec3::Vec3(const Vec3 &a)
	{
		X = a.X;
		Y = a.Y;
		Z = a.Z;
	}

	Vec3::Vec3(const Vec2 &a, float z)
	{
		X = a.X;
		Y = a.Y;
		Z = z;
	}

	Vec3::Vec3(float x, float y, float z)
	{
		X = x;
		Y = y;
		Z = z;
	}

	Vec3::~Vec3()
	{
	}

	Vec3 &Vec3::operator =(const Vec3 &a)
	{
		X = a.X;
		Y = a.Y;
		Z = a.Z;
		return *this;
	}
	bool Vec3::operator ==(const Vec3 &a) const
	{
		return X == a.X && Y == a.Y && Z == a.Z;
	}
	bool Vec3::operator !=(const Vec3 &a) const
	{
		return X != a.X || Y != a.Y || Z != a.Z;
	}
	Vec3 Vec3::operator -() const
	{
		return Vec3(-X, -Y, -Z);
	}
	Vec3 Vec3::operator +(const Vec3 &a) const
	{
		return Vec3(X + a.X, Y + a.Y, Z + a.Z);
	}
	Vec3 Vec3::operator -(const Vec3 &a) const
	{
		return Vec3(X - a.X, Y - a.Y, Z - a.Z);
	}
	Vec3 Vec3::operator *(float a) const
	{
		return Vec3(a * X, a * Y, a * Z);
	}
	Vec3 Vec3::operator /(float a) const
	{
		if (a == 0) return *this;
		float ar = 1.0f / a;
		return Vec3(ar * X, ar * Y, ar * Z);
	}
	Vec3 &Vec3::operator +=(const Vec3 &a)
	{
		X += a.X;
		Y += a.Y;
		Z += a.Z;
		return *this;
	}
	Vec3 &Vec3::operator -=(const Vec3 &a)
	{
		X -= a.X;
		Y -= a.Y;
		Z -= a.Z;
		return *this;
	}
	Vec3 &Vec3::operator *=(float a)
	{
		X *= a;
		Y *= a;
		Z *= a;
		return *this;
	}
	Vec3 &Vec3::operator /=(float a)
	{
		if (a == 0) return *this;
		float ar = 1.0f / a;
		X *= ar;
		Y *= ar;
		Z *= ar;
		return *this;
	}
	float &Vec3::operator [](int i)
	{
		switch (i)
		{
		case 0:
			return X;
		case 1:
			return Y;
		case 2:
			return Z;
		default:	//is this the right course of action to take
			return X;
		}
	}
	float Vec3::operator *(const Vec3 &a) const
	{
		return X * a.X + Y * a.Y + Z * a.Z;
	}

	float * Vec3::toFloatPtr(void)
	{
		return (float *)this;
	}

	Vec2 Vec3::toVec2(void)
	{
		return Vec2(X, Y);
	}

	void Vec3::normalize()
	{
		float magSq = X*X + Y*Y + Z*Z;
		if (magSq > 0.0f) 
		{ // check for divide-by-zero
			float ar = 1.0f / sqrt(magSq);
			X *= ar;
			Y *= ar;
			Z *= ar;
		}
	}
	void Vec3::zero()
	{
		X = 0.0f;
		Y = 0.0f;
		Z = 0.0f;
	}

	Vec3 operator *(float k, const Vec3 &v) 
	{
		return Vec3(k*v.X, k*v.Y, k*v.Z);
	}

}